package com.jy.oms.framework.asyn.task.executor.filter;

import com.jy.oms.framework.asyn.task.cluster.model.WorkModeEnum;
import com.jy.oms.framework.asyn.task.cluster.model.WorkNode;
import com.jy.oms.framework.asyn.task.cluster.model.WorkNodeExecutableTask;
import com.jy.oms.framework.asyn.task.cluster.registry.IRegistryService;
import com.jy.oms.framework.asyn.task.core.ExecutorContext;
import com.jy.oms.framework.asyn.task.executor.ITaskControllerFilter;
import com.jy.oms.framework.asyn.task.model.TaskGroup;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 集群模式工作节点可执行任务校验
 *
 * @author liuquan
 */
@Service
public class GroupClusterExecutableControllerFilter implements ITaskControllerFilter {

    @Autowired
    private IRegistryService registryService;

    @Override
    public boolean checkTaskGroupAbleRun(TaskGroup taskGroup) {
        if (!ExecutorContext.getExecutorConfig().isEnableCluster()) {
            return true;
        }

        WorkNode workNode = registryService.getWorkNode();
        if (workNode.getWorkModel() == WorkModeEnum.SHARE) {
            Pair<Boolean, WorkNodeExecutableTask> ableCollect = workNode.ableCollectShareTask(taskGroup);
            //任务组独享模式，其他节点不能执行此任务组
            if (!ableCollect.getLeft() && CollectionUtils.isEmpty(ableCollect.getRight().getTaskCodes())) {
                return false;
            }
        } else {
            if (CollectionUtils.isNotEmpty(workNode.getMergedExecutableTasks())) {
                //只允许执行指定任务组任务
                WorkNodeExecutableTask workNodeExecutableTask = workNode.getMergedExecutableTasks().stream()
                        .filter(e -> e.getTaskGroup().equals(taskGroup.getGroup()))
                        .findFirst().orElse(null);
                if (workNodeExecutableTask == null) {
                    return false;
                }
            }
        }

        return true;
    }
}
